import { onMounted, onBeforeUnmount } from 'vue'

// 创建WebSocketService实例
class WebSocketService {
  // 成员对象
  constructor(url) {
    this.url = url // WebSocket服务器URL
    this.socket = null // WebSocket实例
    this.izAlive = false // 用于判断心跳是否正常
    this.reconnNums = 0 // 重连尝试次数
    this.heartBeatTimer = null // 心跳定时器
    this.reconnTimer = null // 重连定时器
    // 调用连接
    this.connect()
  }

  // 连接
  connect() {
    this.socket = new WebSocket(this.url)

    this.socket.onopen = () => {
      console.log('WebSocket连接已建立！')
      this.reconnNums = 0 // 成功连接后重置重试次数
      this.startHeartbeat() // 开始心跳检测
    }

    this.socket.onmessage = (event) => {}

    this.socket.onclose = () => {
      console.warn('WebSocket连接已关闭！')
      this.stopHeartbeat()
      this.reconnect()
    }

    this.socket.onerror = (error) => {}
  }

  // 开始心跳检测
  startHeartbeat() {
    this.heartBeatTimer = setInterval(() => {
      if (this.socket.readyState === WebSocket.OPEN) {
        this.izAlive = false
        this.sendPing()
      }
    }, 30000)
  }

  // 停止心跳检测
  stopHeartbeat() {
    if (this.heartBeatTimer) {
      clearInterval(this.heartBeatTimer)
      this.heartBeatTimer = null
    }
  }

  // 发送Ping
  sendPing() {
    this.socket.send('ping')
    this.socket.onmessage = (event) => {
      if (event.data === 'pong') {
        this.izAlive = true
      }
      if (!this.izAlive) {
        console.warn('WebSocket心跳检测失败，尝试重新连接...')
        this.socket.close()
      }
    }
  }

  // 尝试重连
  reconnect() {
    if (this.reconnNums < 5) {
      this.reconnNums++
      console.log(`尝试重新连接(${this.reconnNums})...`)
      this.reconnTimer = setTimeout(() => {
        this.connect()
      }, 1000 * this.reconnNums) // 指数退避算法
    } else {
      console.error('已达到最大重连次数，无法重新连接！')
    }
  }

  // 发送消息
  sendMessage(message) {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(message))
    }
  }

  // 关闭连接
  close() {
    this.stopHeartbeat()
    if (this.reconnTimer) {
      clearTimeout(this.reconnTimer)
      this.reconnTimer = null
    }
    if (this.socket) {
      this.socket.close()
      this.socket = null
    }
  }
}

const useWebSocket = (url) => {
  const ws = new WebSocketService(url)
  let izConn = false

  // 连接成功
  const onOpen = (callback) => {
    ws.socket.onopen = () => {
      izConn = true
      callback()
    }
  }

  // 发送\接收消息
  const onMessage = (callback) => {
    ws.socket.onmessage = (event) => {
      callback(event.data)
    }
  }

  // 关闭连接
  const onClose = (callback) => {
    ws.socket.onclose = () => {
      izConn = false
      callback()
    }
  }

  // 加载
  onMounted(() => {
    onOpen(() => console.log('连接成功！'))
    onClose(() => console.log('未连接！'))
    onMessage((data) => console.log('接收消息：', data))
  })

  // 卸载
  onBeforeUnmount(() => {
    ws.close()
  })

  return { izConn, sendMessage: ws.sendMessage.bind(ws) }
}

export default useWebSocket